package com.huiminpay.transaction.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.huiminpay.common.cache.Cache;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.common.cache.util.RedisUtil;
import com.huiminpay.common.cache.util.StringUtil;
import com.huiminpay.transaction.api.PayChannelService;
import com.huiminpay.transaction.convert.PayChannelParamConvert;
import com.huiminpay.transaction.convert.PlatformChannelConvert;
import com.huiminpay.transaction.dto.PayChannelDTO;
import com.huiminpay.transaction.dto.PayChannelParamDTO;
import com.huiminpay.transaction.dto.PlatformChannelDTO;
import com.huiminpay.transaction.entity.AppPlatformChannel;
import com.huiminpay.transaction.entity.PayChannelParam;
import com.huiminpay.transaction.entity.PlatformChannel;
import com.huiminpay.transaction.mapper.AppPlatformChannelMapper;
import com.huiminpay.transaction.mapper.PayChannelParamMapper;
import com.huiminpay.transaction.mapper.PlatformChannelMapper;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Author: yz
 * @Date: 2024/7/23 14:21
 */
@Service
public class PayChannelServiceImpl implements PayChannelService {
    @Resource
    private PlatformChannelMapper platformChannelMapper;
    @Resource
    private AppPlatformChannelMapper appPlatformChannelMapper;
    @Autowired
    PayChannelParamMapper payChannelParamMapper;
    @Autowired
    Cache cache;
    /**
     * 查询所有服务类型
     *
     * @return 服务类型集合
     */
    @Override
    public List<PlatformChannelDTO> queryPlatFormChannel() throws BusinessException {
        List<PlatformChannel> platformChannels = platformChannelMapper.selectList(null);
        return PlatformChannelConvert.INSTANCE.listentity2listdto(platformChannels);
    }

    /**
     * 为应用绑定服务类型
     *
     * @param appid               应用id
     * @param platformChannelCode 服务类型code
     * @throws BusinessException
     */
    @Override
    public void bindPlatformChannelForApp(String appid, String platformChannelCode) throws BusinessException {
        //判断应用是否已绑定服务
        /*AppPlatformChannel platformChannel = appPlatformChannelMapper.selectOne(
                new LambdaQueryWrapper<AppPlatformChannel>()
                        .eq(AppPlatformChannel::getAppId, appid)
                        .eq(AppPlatformChannel::getPlatformChannel, platformChannelCode)
        );*/
        int platformChannel = queryAppBindPlatformChannel(appid, platformChannelCode);
        if (platformChannel==0){
            AppPlatformChannel appPlatformChannel = new AppPlatformChannel();
            appPlatformChannel.setAppId(appid);
            appPlatformChannel.setPlatformChannel(platformChannelCode);

            //添加绑定关系
            appPlatformChannelMapper.insert(appPlatformChannel);
        }
    }

    /**
     * 应用是否已经绑定了某个服务类型
     *
     * @param appid               应用id
     * @param platformChannelCode 服务类型code
     * @return 0为绑定 1已绑定
     * @throws BusinessException
     */
    @Override
    public int queryAppBindPlatformChannel(String appid, String platformChannelCode) throws BusinessException {
        Integer i = appPlatformChannelMapper.selectCount(
                new LambdaQueryWrapper<AppPlatformChannel>()
                        .eq(AppPlatformChannel::getAppId, appid)
                        .eq(AppPlatformChannel::getPlatformChannel, platformChannelCode)
        );
        if (i==0){
            return 0;
        }
        return 1;
    }

    /**
     * 根据平台类型回去支付渠道列表
     *
     * @param platformChannelCode 平台类型
     * @return
     * @throws BusinessException
     */
    @Override
    public List<PayChannelDTO> queryPayChannelByPlatformChannel(String platformChannelCode) throws BusinessException {
        return platformChannelMapper.selectPayChannelByPlatformCode(platformChannelCode);

    }

    /**
     * 配置支付渠道参数
     *
     * @param payChannelParamDTO 支付渠道参数
     * @throws BusinessException
     */
    @Override
    public void createPayChannelParam(PayChannelParamDTO payChannelParamDTO) throws BusinessException {
        if (payChannelParamDTO==null || payChannelParamDTO.getMerchantId() == null
                || StringUtil.isBlank(payChannelParamDTO.getAppId())
                || StringUtil.isBlank(payChannelParamDTO.getPlatformChannelCode())
                || StringUtil.isBlank(payChannelParamDTO.getChannelName())
                || StringUtil.isBlank(payChannelParamDTO.getPayChannel())){
                throw new BusinessException(CommonErrorCode.E_300009);
        }
        String appId = payChannelParamDTO.getAppId();
        String platformChannelCode = payChannelParamDTO.getPlatformChannelCode();

        Long id=selectIdByAppIdAndPlatFormChannelCode(appId, platformChannelCode);
        if (id == null) {
            throw new BusinessException(CommonErrorCode.E_300010);
        }
        //根据应用与服务类型的绑定id和支付方式 查询参数是否存在
        PayChannelParam payChannelParam = payChannelParamMapper.selectOne(
                new LambdaQueryWrapper<PayChannelParam>()
                        .eq(PayChannelParam::getAppPlatformChannelId, id)
                        .eq(PayChannelParam::getPayChannel, payChannelParamDTO.getPayChannel())
        );
        if (payChannelParam != null) { //修改参数配置
            payChannelParam.setChannelName(payChannelParamDTO.getChannelName());//修改配置名称
            payChannelParam.setParam(payChannelParamDTO.getParam()); //修改参数
            payChannelParamMapper.updateById(payChannelParam);
        }else{
            //新增参数配置
            PayChannelParam payChannelParamEntity = PayChannelParamConvert.INSTANCE.dto2entity(payChannelParamDTO);
            payChannelParamEntity.setAppPlatformChannelId(id); //设置应用与服务类型的绑定id前端没有，需要手动设置
            payChannelParamMapper.insert(payChannelParamEntity);
        }
        //更新缓存
        updateParamCache(appId, platformChannelCode);

    }

    /**
     * 更新缓存
     * @param appId
     * @param platformChannelCode
     */
    private void updateParamCache(String appId, String platformChannelCode) {
        //创建key k:v
        String key = RedisUtil.keyBuilder(appId, platformChannelCode);
        //判断是否存在，
        //存在先删除
        if (cache.exists(key)){
            cache.del(key);
        }
        //在查询并设置缓存
        queryPayChannelParamByAppIdAndPlatformChannelCode(appId, platformChannelCode);
    }

    /**
     * 根据应用和服务类型查询支付渠道参数列表
     *
     * @param appId
     * @param platformChannelCode
     * @return
     * @throws BusinessException
     */
    @Override
    public List<PayChannelParamDTO> queryPayChannelParamByAppIdAndPlatformChannelCode(String appId, String platformChannelCode) throws BusinessException {
        //先去缓存中查
        String key = RedisUtil.keyBuilder(appId, platformChannelCode);
        //如果缓存中有，直接返回数据
        if (cache.exists(key)){
            String s = cache.get(key); //获取缓存数据
            return JSON.parseArray(s, PayChannelParamDTO.class); //缓存中是json字符串，需要转换成对象
        }

        Long id = selectIdByAppIdAndPlatFormChannelCode(appId, platformChannelCode);
        if (id==null) {
            throw new BusinessException(CommonErrorCode.E_300010);
        }
        List<PayChannelParam> payChannelParams = payChannelParamMapper.selectList(
                new LambdaQueryWrapper<PayChannelParam>()
                        .eq(PayChannelParam::getAppPlatformChannelId, id)
        );
        //转换实体类为DTO转换 否则可能回出现类转换异常
        List<PayChannelParamDTO> payChannelParamDTOS = PayChannelParamConvert.INSTANCE.listentity2listdto(payChannelParams);
        //查询到之后，放到缓存中一份
        cache.set(key, JSON.toJSONString(payChannelParamDTOS));
        return payChannelParamDTOS;

    }

    /**
     * 根据应用、服务类型及支付渠道获取原始支付参数
     *
     * @param appId
     * @param platformChannelCode
     * @param payChannelCode
     * @return
     * @throws BusinessException
     */
    @Override
    public PayChannelParamDTO queryPayChannelParamByAppIdAndPlatformChannelCodeAndPayChannelCode(String appId, String platformChannelCode, String payChannelCode) throws BusinessException {
        List<PayChannelParamDTO> params = queryPayChannelParamByAppIdAndPlatformChannelCode(appId, platformChannelCode);
        if (params!=null){
            for (PayChannelParamDTO param : params) {
                if (param.getPayChannel().equals(payChannelCode)) {
                    return param;
                }
            }
        }
        return null;
    }


    /**
     * 查询应用和服务类型绑定id
     * @param appId
     * @param platformChannelCode
     * @return
     */
    private Long selectIdByAppIdAndPlatFormChannelCode(String appId, String platformChannelCode) {
        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(
                new LambdaQueryWrapper<AppPlatformChannel>()
                        .eq(AppPlatformChannel::getAppId, appId)
                        .eq(AppPlatformChannel::getPlatformChannel, platformChannelCode)
        );
        if (appPlatformChannel==null){
            return null;
        }
        return appPlatformChannel.getId(); //返回应用与服务类型的绑定id
    }

}